package com.ch.light.web.service.impl;

import com.ch.light.core.Response;
import com.ch.light.mybatis.ParamFilter;
import com.ch.light.web.entity.pojo.MenuTitle;
import com.ch.light.web.mapper.MenuMapper;
import com.ch.light.web.model.Menu;
import com.ch.light.web.model.Role;
import com.ch.light.web.service.MenuService;
import com.ch.light.web.service.RoleMenuService;
import com.ch.light.web.service.RoleService;
import com.ch.light.web.util.ResourceTreeUtil;
import com.ch.utils.CommonUtils;
import com.ch.utils.UUIDGenerator;
import com.github.pagehelper.PageHelper;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

@Service
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private RoleService roleService;

    @Autowired
    private RoleMenuService roleMenuService;

    @Override
    public void add(Menu menu) {
        checkNotNull(menu, "菜单信息不能为空");
        checkArgument(!Strings.isNullOrEmpty(menu.getIsShow()), "菜单是否显示不正确");
        checkArgument(!Strings.isNullOrEmpty(menu.getType()), "菜单类型不正确");
        if ("1".equals(menu.getType())) {
            checkArgument(!Strings.isNullOrEmpty(menu.getUrl()), "菜单地址不能为空");
        }
        if (!Strings.isNullOrEmpty(menu.getParentId()) && !"#".equals(menu.getParentId())) {
            Menu parentMenu = this.detail(menu.getParentId());
            checkArgument(parentMenu != null, "父菜单不存在");
            checkArgument("0".equals(parentMenu.getType()), "按钮不能添加子菜单");
            menu.setParentName(parentMenu.getName());
        }
        String menuId = UUIDGenerator.generate();
        menu.setCode(menuId);
        menuMapper.insertSelective(menu);
    }

    @Override
    public void delete(List<String> menuIds) {
        checkArgument((menuIds != null && menuIds.size() > 0), "菜单编号不能为空");
        List<Menu> records = Lists.newArrayList();
        for (String menuId : menuIds) {
            List<Menu> menus = this.getByParentId(menuId);
            records.addAll(menus);
        }
        records.forEach(r -> menuMapper.delete(r));
    }

    @Override
    public Menu findByCode(String code) {
        checkArgument(!Strings.isNullOrEmpty(code), "角色标识不能为空");
        Menu param = new Menu();
        param.setCode(code);
        return menuMapper.selectOne(param);
    }

    @Override
    public void update(Menu menu) {
        checkNotNull(menu, "菜单不能为空");
        checkArgument(!Strings.isNullOrEmpty(menu.getCode()), "菜单编号不能为空");
        checkArgument(!Strings.isNullOrEmpty(menu.getName()), "菜单名称不能为空");
        checkArgument(!Strings.isNullOrEmpty(menu.getIsShow()), "菜单是否显示不正确");
        checkArgument(!Strings.isNullOrEmpty(menu.getType()), "菜单类型不正确");
        if ("1".equals(menu.getType())) {
            checkArgument(!Strings.isNullOrEmpty(menu.getUrl()), "菜单地址不能为空");
        }
        Menu model = findByCode(menu.getCode());
        checkNotNull(model, "菜单不存在");
        menuMapper.updateByPrimaryKey(menu);
    }

    @Override
    public List<MenuTitle> getListByRoleId(String roleId) {
        checkArgument(!Strings.isNullOrEmpty(roleId), "角色编号不能为空");
        Role model = roleService.getByRoleId(roleId);
        checkNotNull(model, "角色不存在");
        return this.loadResources(roleId);
    }

    @Override
    public List<Menu> getByParentId(String menuId) {
        List<Menu> menuList = Lists.newLinkedList();
        Menu parentMenu = findByCode(menuId);
        if (parentMenu != null) {
            menuList.add(parentMenu);
        }
        Menu param = new Menu();
        param.setParentId(menuId);
        List<Menu> subMenuList = menuMapper.select(param);
        menuList.addAll(subMenuList);
        return menuList;
    }

    private List<MenuTitle> loadResources(String roleId) {
        Map<String, List<MenuTitle>> roleResMap = Maps.newHashMap();
        //从缓存取菜单
        // roleResMap = cacheManager.get( key, Map.class, cacheCallback );
        /*List<MenuTitle> list = roleResMap.get(roleId);
        if (list != null) {
            return list;
        }*/
        List<String> menuCodeList = roleMenuService.getMenuByRoleId(roleId);
        if (CommonUtils.isEmpty(menuCodeList)) {
            return Lists.newArrayList();
        }
        Map<String, List<Menu>> map = new HashMap<>();
        List<MenuTitle> list = Lists.newArrayList();
        menuCodeList.forEach(r -> {
            Menu menu = findByCode(r);
            if (menu == null || "1".equals(menu.getType())) {
                return;
            }
            String parentId = menu.getParentId();
            List<Menu> subList = map.get(parentId);
            if (subList == null) {
                subList = new ArrayList<>(8);
                MenuTitle title = new MenuTitle();
                Menu parentMenu = findByCode(parentId);
                if (parentMenu == null) {
                    //boolean isEmpty = BeanUtil.isEmpty(map.get(menu.getCode()));
                    title.setName(menu.getName());
                    title.setSeq(menu.getSort());
                    title.setMenuList(subList);
                    title.setTitleId(menu.getCode());
                    title.setIcon(menu.getIcon());
                    if (CommonUtils.isEmpty(map.get(menu.getCode()))) {
                        list.add(title);
                        map.put(title.getTitleId(), subList);
                    }
                    return;
                }
                title.setMenuList(subList);
                title.setName(parentMenu.getName());
                title.setIcon(parentMenu.getIcon());
                title.setSeq(parentMenu.getSort());
                list.add(title);
                map.put(parentId, subList);
            }
            subList.add(menu);
        });

        for (List<Menu> resources : map.values()) {
            resources.sort((e1, e2) -> CommonUtils.compareTo(e1.getSort(), e2.getSort()));
        }
        list.sort((e1, e2) -> CommonUtils.compareTo(e1.getSeq(), e2.getSeq()));
        roleResMap.put(roleId, list);
        return list;
    }

    @Override
    public List<Menu> getList(ParamFilter paramFilter) {
        int pageNum = paramFilter.getPage().getPageNo();
        int pageSize = paramFilter.getPage().getPageSize();
        PageHelper.startPage(pageNum, pageSize, true, false, false);
        Example example = new Example(Menu.class);
        Map<String, Object> param = paramFilter.getParam();
        return menuMapper.selectByExample(example);
    }

    @Override
    public Response getResTree(String roleId) {
        Response response = new Response();
        if (Strings.isNullOrEmpty(roleId)) {
            response.setCode(Response.INVALID_PARAM);
            response.setMsg("角色编号不能为空");
            return response;
        }
        Map<String, String> paramMap = Maps.newHashMap();
        paramMap.put("roleId", roleId);
        List<Map<String, Object>> resList = menuMapper.findTreeByRoleId(roleId);
        response.setData(ResourceTreeUtil.generateJSTree(resList));
        return response;
    }

    @Override
    public Response getSelectResTree() {
        Response response = new Response();

        Menu param = new Menu();
        param.setParentId("#");
        List<Menu> parents = menuMapper.select(param);
       /* List<Map<String, Object>> parentList = menuDao.findMap("getMenuIdAndName", BigInteger.ZERO.toString());
        List<Map<String, Object>> resList = new LinkedList<>();
        for (Map<String, Object> resMap : parentList) {
            List<Menu> subRes = menuDao.find("getMenuByParentId", resMap.get("menuId"));
            Map<String, Object> subMap;
            resList.add(resMap);
            for (Menu menu : subRes) {
                subMap = Maps.newHashMap();
                String subName = menu.getName();
                subName = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" + subName;
                subMap.put("resId", menu.getCode());
                subMap.put("name", subName);
                resList.add(subMap);
            }
        }
        response.setData(resList);*/
        return response;
    }

    @Override
    public Menu detail(String resId) {
        Response response = new Response();
        if (Strings.isNullOrEmpty(resId)) {
            response.setCode(Response.INVALID_PARAM);
            response.setMsg("资源编号不能为空");
        }
        return findByCode(resId);
    }

    @SuppressWarnings("rawtypes")
    @Override
    public Response getTree() {
        Response response = new Response();
        List resList = menuMapper.findTree();
        response.setData(resList);
        return response;
    }

    @Override
    public List<String> findCodeByRoleId(String roleId) {
        return menuMapper.findCodeByRoleId(roleId);
    }
}
